package com.mmd.manage.service.impl;

import com.github.pagehelper.PageInfo;
import com.mmd.bean.CODE;
import com.mmd.bean.UserLoginContext;
import com.mmd.common.entity.*;
import com.mmd.common.enums.BillTypeEnums;
import com.mmd.common.enums.UserTypeEnums;
import com.mmd.common.enums.YesNoEnums;
import com.mmd.exception.GameException;
import com.mmd.intercepter.AdminInterceptor;
import com.mmd.manage.dao.*;
import com.mmd.manage.service.BillService;
import com.mmd.manage.vo.*;
import com.mmd.utils.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class BillServiceImpl implements BillService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private MmdBillRecordDao mmdBillRecordDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private MmdOrderDao mmdOrderDao;
    @Autowired
    private SuOrderDao suOrderDao;
    @Autowired
    private MmdOrderDetailDao mmdOrderdetailDao;
    @Autowired
    private MmdOrderProductDao mmdOrderProductDao;

    @Override
    public boolean addAmount(AddAmountEo eo) {
        UserLoginContext userLoginContext = AdminInterceptor.getUserLoginContext();
        if (userLoginContext.getLevel().equals("admin")) {
            MmdUser mmdUser = userDao.selectByPrimaryKey(eo.getUid());
            if (mmdUser == null) {
                throw new GameException(new CODE(9999, "用户不存在"));
            }
            //保存账单的账单
            MmdBillRecord record = new MmdBillRecord();
            record.setBusinessNo(null);
            record.setCreateTime(new Date());
            record.setUserType(UserTypeEnums.USER.getCode());
            record.setUid(mmdUser.getUid());
            record.setAmcount(eo.getAmount());
            record.setType(BillTypeEnums.CHARGE.getCode());
            MmdBillRecord maxRecord = mmdBillRecordDao.selectMaxBill(mmdUser.getUid());
            record.setTotalAmount(eo.getAmount());
            if (maxRecord != null) {
                record.setTotalAmount(maxRecord.getTotalAmount().add(eo.getAmount()));
            }
            record.setRemark(eo.getRemark());
            mmdBillRecordDao.insert(record);
        }
        //供应商给管理员充值
        if (userLoginContext.getLevel().equals("supplier")) {
            //保存账单的账单
            MmdBillRecord record = new MmdBillRecord();
            record.setBusinessNo(null);
            record.setCreateTime(new Date());
            record.setUserType(UserTypeEnums.SUP.getCode());
            record.setUid(userLoginContext.getUid());
            record.setAmcount(eo.getAmount().negate());
            record.setType(BillTypeEnums.CHARGE.getCode());
            List<MmdUser> mmdUsers = userDao.selectByKeySelective(new MmdUser());
            MmdUser mmdUser = mmdUsers.stream().filter(user -> user.getLevel().equals("admin")).findAny().orElse(null);
            if (mmdUser == null) {
                throw new GameException(new CODE(9999, "管理员账号不存在"));
            }
            MmdBillRecord maxRecord = mmdBillRecordDao.selectMaxBill(mmdUser.getUid());
            //对应供应商而已是待收，所以是负数
            record.setTotalAmount(eo.getAmount().negate());
            if (maxRecord != null) {
                record.setTotalAmount(maxRecord.getTotalAmount().add(eo.getAmount().negate()));
            }
            mmdBillRecordDao.insert(record);
        }
        return true;
    }


    @Override
    public PageData<QueryBillListVo> getUserBillList(QueryBillListEo eo) {
        eo.setStartLimit((eo.getCurPage() - 1) * eo.getPageSize());
        List<QueryBillListVo> list = mmdBillRecordDao.getUserBillList(eo);
        for (QueryBillListVo queryBillListVo : list) {
            queryBillListVo.setBillTypeName(BillTypeEnums.getUserTypeEnum(queryBillListVo.getType()).getName());
        }
        PageInfo<QueryBillListVo> result = new PageInfo<>(list);
        Integer count = mmdBillRecordDao.countUserBillList(eo);
        result.setTotal(count);
        PageData<QueryBillListVo> data = new PageData<>(result);
        data.setCurPage(eo.getCurPage());
        data.setPageSize(eo.getPageSize());
        return data;
    }


    @Override
    public PageData<QueryBillListVo> getSupBillList(QueryBillListEo eo) {
        eo.setStartLimit((eo.getCurPage() - 1) * eo.getPageSize());
        List<QueryBillListVo> list = mmdBillRecordDao.getSupBillList(eo);
        for (QueryBillListVo queryBillListVo : list) {
            if (Objects.equals(queryBillListVo.getType(), BillTypeEnums.CONSUMER.getCode())) {
                queryBillListVo.setAmcount(queryBillListVo.getAmcount().negate());
            }
            queryBillListVo.setBillTypeName(BillTypeEnums.getUserTypeEnum(queryBillListVo.getType()).getName());
        }
        PageInfo<QueryBillListVo> result = new PageInfo<>(list);
        Integer count = mmdBillRecordDao.countSupBillList(eo);
        result.setTotal(count);
        PageData<QueryBillListVo> data = new PageData<>(result);
        data.setCurPage(eo.getCurPage());
        data.setPageSize(eo.getPageSize());
        return data;
    }


    @Override
    public PageData<QueryBillListVo> getUserBills(QueryBillListEo eo) {
        eo.setCurrUid(AdminInterceptor.getUserLoginContext().getUid());
        eo.setStartLimit((eo.getCurPage() - 1) * eo.getPageSize());
        List<QueryBillListVo> list = mmdBillRecordDao.getUserBills(eo);
        for (QueryBillListVo queryBillListVo : list) {
            queryBillListVo.setBillTypeName(BillTypeEnums.getUserTypeEnum(queryBillListVo.getType()).getName());
        }
        PageInfo<QueryBillListVo> result = new PageInfo<>(list);
        Integer count = mmdBillRecordDao.countUserBills(eo);
        result.setTotal(count);
        PageData<QueryBillListVo> data = new PageData<>(result);
        data.setCurPage(eo.getCurPage());
        data.setPageSize(eo.getPageSize());
        return data;
    }

    @Override
    public PageData<QueryBillListVo> getAdminBills(QueryBillListEo eo) {
        eo.setCurrUid(AdminInterceptor.getUserLoginContext().getUid());
        eo.setStartLimit((eo.getCurPage() - 1) * eo.getPageSize());
        List<QueryBillListVo> list = mmdBillRecordDao.getAdminBills(eo);
        for (QueryBillListVo queryBillListVo : list) {
            queryBillListVo.setBillTypeName(BillTypeEnums.getUserTypeEnum(queryBillListVo.getType()).getName());
        }
        PageInfo<QueryBillListVo> result = new PageInfo<>(list);
        Integer count = mmdBillRecordDao.countAdminBills(eo);
        result.setTotal(count);
        PageData<QueryBillListVo> data = new PageData<>(result);
        data.setCurPage(eo.getCurPage());
        data.setPageSize(eo.getPageSize());
        return data;
    }

    @Override
    public List<ExportYsYfVo> getExportYsYfVoList(String startTime, String endTime) {
        List<MmdOrder> orderList = mmdOrderDao.getMmdOrderList(startTime, endTime);
        String level = AdminInterceptor.getUserLoginContext().getLevel();
        List<ExportYsYfVo> resultList = orderList.stream().map(mmdOrder -> {
            ExportYsYfVo vo = new ExportYsYfVo();
            vo.setBusinessDate(DateUtil.msToDate(mmdOrder.getCreateTime().getTime()));
            MmdUser user = userDao.selectByPrimaryKey(mmdOrder.getUid());
            vo.setCustomer(user==null?"":user.getUserName());
            vo.setOrderNo(mmdOrder.getOrderNo());
            vo.setTrackingNo(mmdOrder.getLogisticsNo());
            vo.setDestinationCountry(mmdOrder.getDestinationCountry());
            vo.setChannel(mmdOrder.getRouteName());

            List<MmdOrderDetailVo> orderDetailList = mmdOrderdetailDao.list(mmdOrder.getOrderNo());
            vo.setNumber(orderDetailList.size());
            vo.setWeightSum(mmdOrder.getChargedWeight().toString());

            Set<String> productNameSet = new HashSet<>();
            List<MmdOrderProduct> orderProductList = mmdOrderProductDao.listByOrderNo(mmdOrder.getOrderNo(), level);
            for (MmdOrderProduct mmdOrderProduct : orderProductList){
                productNameSet.add(mmdOrderProduct.getProductCnName());
            }
            String productTypeName = "";
            int index = 0;
            for (String productName : productNameSet){
                productTypeName = productTypeName + productName;

                if (index < (productNameSet.size() - 1)){
                    productTypeName = productTypeName + ",";
                }
                index++;
            }
            vo.setProductTypeName(productTypeName);
            vo.setSinglePrice(mmdOrder.getChargedPrice()==null? BigDecimal.ZERO:mmdOrder.getChargedPrice());
            vo.setAttachFee(mmdOrder.getAttachFee()==null?BigDecimal.ZERO:mmdOrder.getAttachFee());
            BigDecimal singleDeclareFee = mmdOrder.getSingleDeclareFee()==null?BigDecimal.ZERO:mmdOrder.getSingleDeclareFee();
            BigDecimal singleOperatFee = mmdOrder.getSingleOperatFee()==null?BigDecimal.ZERO:mmdOrder.getSingleOperatFee();
            vo.setSingleDeclareOrOperatFee(singleDeclareFee.add(singleOperatFee));
            vo.setTotalFee(mmdOrder.getTotalFee()==null?BigDecimal.ZERO:mmdOrder.getTotalFee());
            vo.setRemark("");
            vo.setChooseSup(mmdOrder.getChooseSup());
            if (mmdOrder.getChooseSup() == YesNoEnums.YES.getCode()){
                SuOrder suOrder = suOrderDao.getSuOrderByBatchNo(mmdOrder.getBatchNo());
                if (suOrder != null){
                    vo.setSu_weightSum(suOrder.getChargedWeight()==null?"":suOrder.getChargedWeight().toString());
                    vo.setSu_singlePrice(suOrder.getChargedPrice()==null?BigDecimal.ZERO:suOrder.getChargedPrice());
                    vo.setSu_attachFee(suOrder.getAttachFee()==null?BigDecimal.ZERO:suOrder.getAttachFee());
                    BigDecimal su_singleDeclareFee = suOrder.getSingleDeclareFee()==null?BigDecimal.ZERO:suOrder.getSingleDeclareFee();
                    BigDecimal su_singleOperatFee = suOrder.getSingleOperatFee()==null?BigDecimal.ZERO:suOrder.getSingleOperatFee();
                    vo.setSu_singleDeclareOrOperatFee(su_singleDeclareFee.add(su_singleOperatFee));
//                    vo.setSu_cost(BigDecimal.ZERO);
                    vo.setSu_transportFee(suOrder.getTotalFee()==null?BigDecimal.ZERO:suOrder.getTotalFee());
                    vo.setSu_grossProfit(vo.getTotalFee().subtract(vo.getSu_transportFee()));
                }
            }
            return vo;
        }).collect(Collectors.toList());
        return resultList;
    }

    @Override
    public List<UserListVo> userList() {
        List<MmdUser> mmdUsers = userDao.selectByKeySelective(new MmdUser());
        String level = AdminInterceptor.getUserLoginContext().getLevel();

        List<UserListVo> vos = new ArrayList<>();
        if ("admin".equals(level)) {
            for (MmdUser mmdUser : mmdUsers) {
                if (mmdUser.getLevel().equals("user")) {
                    UserListVo vo = new UserListVo();
                    vo.setUid(mmdUser.getUid());
                    vo.setUserName(mmdUser.getUserName());
                    vos.add(vo);
                }
            }
        }

        if ("supplier".equals(level)) {
            MmdUser mmdUser = mmdUsers.stream().filter(user -> user.getLevel().equals("admin")).findAny().orElse(null);
            UserListVo vo = new UserListVo();
            vo.setUid(mmdUser.getUid());
            vo.setUserName(mmdUser.getUserName());
            vos.add(vo);
        }
        return vos;
    }

}
